﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Functions;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Functions.Readers;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Fundamental;
using TSU.FAMC.ComputerEngineering.Classes.Diagnostics.PathDelayFaults;

namespace FullTestSequenceBuilder
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            openFileDialog2.ShowDialog();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            openFileDialog3.ShowDialog();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            openFileDialog4.ShowDialog();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            // Verifying
            if (openFileDialog1.FileNames.Length == 0)
            {
                MessageBox.Show("Вы не выбрали исходные a,b-тесты!");
                return;
            }
            if (openFileDialog2.FileNames.Length == 0)
            {
                MessageBox.Show("Вы не выбрали исходные робастные тесты!");
                return;
            }
            if (openFileDialog3.FileNames.Length == 0)
            {
                MessageBox.Show("Вы не выбрали исходные не робастные тесты!");
                return;
            }
            if (openFileDialog4.FileNames.Length == 0)
            {
                MessageBox.Show("Вы не выбрали сокращенные общие тесты тесты!");
                return;
            }

            if (openFileDialog1.FileNames.Length != openFileDialog2.FileNames.Length ||
                openFileDialog1.FileNames.Length != openFileDialog3.FileNames.Length ||
                openFileDialog1.FileNames.Length != openFileDialog4.FileNames.Length)
            {
                MessageBox.Show("Выбраны несовместимые тесты!");
                return;
            }


            // selecting output folder
            if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
            {
                MessageBox.Show("Выберите директорию для результатов!");
                return;
            }


            for (var j = 0; j < openFileDialog1.FileNames.Length; j++)
            {
                var abFileName = openFileDialog1.FileNames[j];
                var robustFileName = openFileDialog2.FileNames[j];
                var nonRobustFileName = openFileDialog3.FileNames[j];
                var compactedFileName = openFileDialog4.FileNames[j];

                var fileName = String.Empty;
                var fileStr = String.Empty;
                var reader = new BooleanSystemReaderPlafd();


                // ----------------------------------------------------------------------------------------
                // reading a,b-tests
                // ----------------------------------------------------------------------------------------

                fileStr = String.Empty;
                fileName = abFileName;

                try
                {
                    // reading file
                    var streamReader = new StreamReader(fileName);
                    fileStr = streamReader.ReadToEnd();
                }
                catch (Exception)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать файл a,b-тестов: {0}!", fileName));
                    return;
                }


                // reading system
                var abSystem = new BooleanSystem();
                reader = new BooleanSystemReaderPlafd();
                reader.Input = fileStr;
                reader.System = abSystem;

                try
                {
                    reader.Read();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать систему a,b-тестов: {0}", ex.Message));
                    return;
                }



                // ----------------------------------------------------------------------------------------
                // reading robust-tests
                // ----------------------------------------------------------------------------------------

                fileStr = String.Empty;
                fileName = robustFileName;

                try
                {
                    // reading file
                    var streamReader = new StreamReader(fileName);
                    fileStr = streamReader.ReadToEnd();
                }
                catch (Exception)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать файл робастных тестов: {0}!", fileName));
                    return;
                }


                // reading system
                var robustSystem = new BooleanSystem();
                reader = new BooleanSystemReaderPlafd();
                reader.Input = fileStr;
                reader.System = robustSystem;

                try
                {
                    reader.Read();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать систему робастных тестов: {0}", ex.Message));
                    return;
                }



                // ----------------------------------------------------------------------------------------
                // reading non-robust-tests
                // ----------------------------------------------------------------------------------------

                fileStr = String.Empty;
                fileName = nonRobustFileName;

                try
                {
                    // reading file
                    var streamReader = new StreamReader(fileName);
                    fileStr = streamReader.ReadToEnd();
                }
                catch (Exception)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать файл не робастных тестов: {0}!", fileName));
                    return;
                }


                // reading system
                var nonRobustSystem = new BooleanSystem();
                reader = new BooleanSystemReaderPlafd();
                reader.Input = fileStr;
                reader.System = nonRobustSystem;

                try
                {
                    reader.Read();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать систему не робастных тестов: {0}", ex.Message));
                    return;
                }



                // ----------------------------------------------------------------------------------------
                // reading compacted-tests
                // ----------------------------------------------------------------------------------------

                fileStr = String.Empty;
                fileName = compactedFileName;

                try
                {
                    // reading file
                    var streamReader = new StreamReader(fileName);
                    fileStr = streamReader.ReadToEnd();
                }
                catch (Exception)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать файл сокращенной системы тестовых векторов: {0}!", fileName));
                    return;
                }


                // reading system
                var compactedSystem = new BooleanSystem();
                reader = new BooleanSystemReaderPlafd();
                reader.Input = fileStr;
                reader.System = compactedSystem;

                try
                {
                    reader.Read();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Не удалось прочитать сокращенную систему тестовых векторов: {0}", ex.Message));
                    return;
                }



                // building sequences

                // building a,b-test sequence
                var abSequence = new List<Cube>();

                foreach (var func in abSystem.Functions)
                {
                    abSequence.AddRange(func.Domain1);
                }


                // building robust sequence
                var robustSequence = new List<Cube>();

                try
                {
                    robustSequence = PdfAnalyzer.BuildCompactedPdfTestSequence(robustSystem, compactedSystem);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

                // filtering a,b-test sequence by robust vectors
                var filteredABSequence = new List<Cube>(abSequence);
                foreach (var cube in robustSequence)
                {
                    // searching for all covered cubes in a,b-sequence to delete
                    foreach (var cube2 in filteredABSequence)
                    {
                        if (cube2.Contains(cube))
                        {
                            abSequence.Remove(cube2);
                        }
                    }

                    // updating filtered a,b-sequence
                    filteredABSequence = new List<Cube>(abSequence);
                }

                // updating a,b-sequence
                abSequence = filteredABSequence;



                // building non-robust sequence
                var nonRobustSequence = new List<Cube>();

                try
                {
                    nonRobustSequence = PdfAnalyzer.BuildCompactedPdfTestSequence(nonRobustSystem, compactedSystem);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }


                // filtering a,b-test sequence by non-robust vectors
                filteredABSequence = new List<Cube>(abSequence);
                foreach (var cube in nonRobustSequence)
                {
                    // searching for all covered cubes in a,b-sequence to delete
                    foreach (var cube2 in filteredABSequence)
                    {
                        if (cube2.Contains(cube))
                        {
                            abSequence.Remove(cube2);
                        }
                    }

                    // updating filtered a,b-sequence
                    filteredABSequence = new List<Cube>(abSequence);
                }

                // updating a,b-sequence
                abSequence = filteredABSequence;



                // writing sequence to file

                var outputFileStr = String.Empty;

                outputFileStr += String.Format(".p {0}", robustSequence.Count + nonRobustSequence.Count + abSequence.Count);
                outputFileStr += "\r\n";
                outputFileStr += "\r\n";

                // writing robust sequence
                foreach (var testVector in robustSequence)
                {
                    outputFileStr += testVector;
                    outputFileStr += "\r\n";
                }

                outputFileStr += "\r\n";

                // writing non-robust sequence
                foreach (var testVector in nonRobustSequence)
                {
                    outputFileStr += testVector;
                    outputFileStr += "\r\n";
                }

                outputFileStr += "\r\n";

                // writing filtered a,b-test sequence
                foreach (var testVector in abSequence)
                {
                    outputFileStr += testVector;
                    outputFileStr += "\r\n";
                }

                outputFileStr += "\r\n";
                outputFileStr += "\r\n";
                outputFileStr += ".e";

                var outputFilePath = folderBrowserDialog1.SelectedPath + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(compactedFileName) + "_seq.test";

                try
                {
                    var streamWriter = new StreamWriter(outputFilePath);
                    streamWriter.Write(outputFileStr);
                    streamWriter.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Output error: {0}.", ex.Message));
                    continue;
                }
            }


            MessageBox.Show("Complete!");
        }
    }
}
